package qc.module.platform.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.enums.FileTypeEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.FileTypeUtil;
import qc.module.platform.dto.file.FileInfoDto;
import qc.module.platform.dto.file.FileQueryConditionDto;
import qc.module.platform.entity.QcFiles;
import qc.module.platform.mapper.FileMapper;
import qc.module.platform.repository.QcFilesRepository;

import java.util.Date;
import java.util.List;

/**
 * FileService
 *
 * @author QuCheng Tech
 * @since 2023/6/8
 */
@Service
public class FileService {
    private QcFilesRepository repository;

    @Autowired
    public void setQcFilesRepository(QcFilesRepository repository) {
        this.repository = repository;
    }

    public Integer add(String title, String originalFileName, String name, String system, String module, String path, String extension, double size) throws QCPromptException {
        QcFiles en = new QcFiles();
        //生成文件ID，获取数据库中的最大id+1后赋值
        Integer fileId = genereateId();
        en.setId(fileId);
        //文件标题，使用传入的title，如果没有title使用原文件名
        if (!StringUtils.isBlank(title))
            en.setTitle(title);
        else if (!StringUtils.isBlank(originalFileName))
            en.setTitle(originalFileName);
        if (!StringUtils.isBlank(name))
            en.setName(name);
        if (!StringUtils.isBlank(system))
            en.setSys(system);
        if (!StringUtils.isBlank(module))
            en.setModule(module);
        if (!StringUtils.isBlank(path))
            en.setPath(path);
        if (!StringUtils.isBlank(extension))
            en.setExtension(extension);
        //判断文件类型
        en.setType(FileTypeUtil.getByExtension(extension));

        en.setSize(size);
        //默认赋值：时间、浏览次数、下载次数
        en.setTm(DateUtil.getNowDate());
        en.setVcount(0x0);
        en.setDcount(0x0);

        if (repository.insert(en) < 0x1)
            throw new QCPromptException("保存文件信息到数据库失败");

        return fileId;
    }

    /**
     * 获取指定ID的文件信息
     *
     * @param fileId 文件ID
     * @return 文件实体类
     * @author QuCheng Tech
     * @since 2023/6/8
     */
    public QcFiles get(Integer fileId) throws QCPromptException {
        if (fileId == null)
            throw new QCPromptException("文件ID不能为空");

        if (!hasIdExist(fileId))
            throw new QCPromptException("指定ID的文件信息不存在");

        return repository.selectById(fileId);
    }


    /**
     * 获取指定ID的文件信息，不包含内容
     *
     * @param id:文件id
     * @return FileInfoDto 获取指定文件信息存在返回文件信息，不存在返回内容null
     * @author QcCheng Tech
     * @date 2023/10/18
     */
    public FileInfoDto getFile(int id) {
        //查询条件
        LambdaQueryWrapper<QcFiles> wrapper = new LambdaQueryWrapper<>();
        //指定查询内容
        wrapper.select(QcFiles::getId, QcFiles::getTitle, QcFiles::getName, QcFiles::getExtension, QcFiles::getType, QcFiles::getSize, QcFiles::getTm, QcFiles::getVcount, QcFiles::getDcount,QcFiles::getPath);
        //查询条件
        wrapper.eq(QcFiles::getId, id);
        QcFiles qcFiles = repository.selectOne(wrapper);
        if (qcFiles == null)
            return null;
        return FileMapper.MAPPER.toDto(qcFiles);
    }

    /**
     * 查看指定ID的文件信息，浏览次数+1
     *
     * @param fileId 文件ID
     * @return 文件实体类
     * @author QuCheng Tech
     * @since 2023/6/8
     */
    public QcFiles view(Integer fileId) throws QCPromptException {
        QcFiles en = get(fileId);

        if (en != null) {
            LambdaUpdateWrapper<QcFiles> wrapper = new LambdaUpdateWrapper<>();
            //次数+1
            wrapper.setSql("vcount=vcount+1");
            wrapper.eq(QcFiles::getId, fileId);

            repository.update(null, wrapper);
        }

        return en;
    }

    /**
     * 下载指定ID的文件，下载次数+1
     *
     * @param fileId 文件ID
     * @return 文件实体类
     * @author QuCheng Tech
     * @since 2023/6/8
     */
    public QcFiles download(Integer fileId) throws QCPromptException {
        QcFiles en = get(fileId);

        if (en != null) {
            LambdaUpdateWrapper<QcFiles> wrapper = new LambdaUpdateWrapper<>();
            //次数+1
            wrapper.setSql("dcount=dcount+1");
            wrapper.eq(QcFiles::getId, fileId);

            repository.update(null, wrapper);
        }

        return en;
    }

    /***
     * 查询文件
     *
     * @param condition 查询条件
     * @return java.util.List<qc.module.platform.dto.file.FileInfoDto>
     * @author QuCheng Tech
     * @since 2023/8/14
     */
    public List<FileInfoDto> query(FileQueryConditionDto condition) throws QCPromptException {
        if (condition == null)
            throw new QCPromptException("查询文件的条件不能为空");
        if (StringUtils.isBlank(condition.getSys()))
            throw new QCPromptException("查询文件的指定的所属系统不能为空");
        if (StringUtils.isBlank(condition.getModule()))
            throw new QCPromptException("查询文件的指定的所属模块不能为空");
        if (StringUtils.isBlank(condition.getBegintm()))
            throw new QCPromptException("查询文件的上传开始时间不能为空");
        if (StringUtils.isBlank(condition.getEndtm()))
            throw new QCPromptException("查询文件的上传截止时间不能为空");

        Date beginTime = null;
        try {
            beginTime = DateUtil.parseDate(condition.getBegintm());
        } catch (Exception e) {
            throw new QCPromptException("查询文件的上传开始时间转换错误");
        }
        Date endTime = null;
        try {
            endTime = DateUtil.parseDate(condition.getEndtm());
        } catch (Exception e) {
            throw new QCPromptException("查询文件的上传截止时间转换错误");
        }
        if (beginTime.after(endTime))
            throw new QCPromptException("查询文件的上传开始时间不能大于截止时间");

        FileTypeEnum fileTypeEnum = getFileTypeEnum(condition.getType());

        LambdaQueryWrapper<QcFiles> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcFiles::getSys, condition.getSys());
        wrapper.eq(QcFiles::getModule, condition.getModule());
        wrapper.ge(QcFiles::getTm, beginTime);
        wrapper.le(QcFiles::getTm, endTime);
        if (fileTypeEnum != FileTypeEnum.UN_KNOW)
            wrapper.eq(QcFiles::getType, fileTypeEnum);

        wrapper.orderByAsc(QcFiles::getTm);

        List<QcFiles> ens = repository.selectList(wrapper);

        if (ens != null && ens.size() > 0x0) {
            return FileMapper.MAPPER.toDtoList(ens);
        }

        return null;
    }

    /**
     * 判断指定的ID是否存在
     *
     * @param id 分类ID
     * @return true表示已存在，false表示不存在
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    public boolean hasIdExist(Integer id) {
        LambdaQueryWrapper<QcFiles> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcFiles::getId, id);

        QcFiles en = repository.selectOne(wrapper);
        if (en != null)
            return true;

        return false;
    }

    /**
     * 生成记录ID，获取数据库表中的最大记录ID+1
     *
     * @return 生成记录ID
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    Integer genereateId() {
        Integer maxRecordId = getMaxId();
        return maxRecordId + 1;
    }

    /**
     * 获取数据库表中的最大ID值，没有记录时返回0
     *
     * @return 返回数据库表中的最大ID值
     * @author QuCheng Tech
     * @since 2023/5/28
     */
    Integer getMaxId() {
        LambdaQueryWrapper<QcFiles> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(QcFiles::getId);
        wrapper.orderByDesc(QcFiles::getId);
        QcFiles en = repository.selectOne(wrapper);
        if (en != null)
            return en.getId();

        return 0x0;
    }

    FileTypeEnum getFileTypeEnum(int type) {
        if (type >= 0x0) {
            for (FileTypeEnum item : FileTypeEnum.values()) {
                if (item.getIndex() == type) {//判断序号使用getIndex，判断内容使用getName
                    return item;
                }
            }
        }

        return FileTypeEnum.UN_KNOW;
    }
}
    
